home *** CD-ROM | disk | FTP | other *** search
-
- /***********************************************************************/
-
- /* File KSEND.C - Send procedures for RML Kermit;
- Chris Kennington, RML. 1st July 1985 */
-
- #define DEFS2 1
- #define DEFS4 1
-
- #include "stdio.h"
- #include "b:kext.h"
-
-
- /* static externals for this file only */
- static char cannot[] = "Cannot open <%s>; ";
- static char mainhas[] = "Mainframe has ";
- static char unable[] = "Nothing from mainframe. ";
- static int num, len; /* Packet number & length */
-
-
-
-
- gnxtfl()
- /* Get next file in a file group; if wildcard, expand it into
- cmdline. Return TRUE or FALSE. */
- {
- char ret;
-
- if (filecount-- == 0) {
- filnam = 0;
- return(FALSE); /* If no more, fail */
- }
- else {
- vtline(LOCFILE,filblank);
- vtline(LOCFILE,(filnam = *(filelist++)));
- printmsg(null);
- if ( ( (ret = fileok(filnam))&(char)0x07 ) != 0 ) {
- txtout("not sent."); /* no file */
- return(gnxtfl()); /* recursive call */
- }
- else if ( (ret&(char)0x40) != 0 ) { /* wildcards */
- printf("Expanding wildcards ...");
- ret = wildex(filnam,cmdline);
- printmsg("Will send: %s",cmdline);
- if (ret > (char)8)
- txtout(" (more on disk)");
- filecount = decol8(cmdline,cmdparm,8);
- filelist = cmdparm;
- return(gnxtfl()); /* recursive call */
- }
- else {
- return(TRUE);
- } } } /* end of gnxtfl() */
-
-
-
-
- char sbreak() /* Send Break (EOT) */
- {
- if (numtry++ > MAXTRY) return('A'); /* If too many tries "abort" */
-
- spack('B',n,0,0); /* Send a B packet */
- switch (rpack(&len,&num,recpkt)) /* What was the reply? */
- {
- case 'N': /* NAK, just stay in this state, */
- num = (--num<0 ? 63:num); /* unless NAK for previous packet, */
-
- case 'Y': /* ACK */
- if (n != num) return(state); /* If wrong ACK, fail */
- inctry(); /* ++n%64 & ++tries */
- printmsg("** All files sent OK. ");
- return('C'); /* Switch state to Complete */
-
- case 'E': /* Error packet received */
- prerrpkt(recpkt); /* Print it out and */
- return('A'); /* abort */
-
- case FALSE: return(state); /* Receive failure, stay in B */
-
- default: /* Other, "abort" */
- printmsg(badmsg,'Y',type);
- return('A');
- }
- } /* end of sbreak() */
-
-
-
-
- char sdata() /* Send File Data */
- {
- if (numtry++ > MAXTRY) return('A'); /* If too many tries, give up */
-
- spack('D',n,size,packet); /* Send a D packet */
- if (abtflag != 0) {
- sendfail();
- return('A');
- }
- switch(rpack(&len,&num,recpkt)) /* What was the reply? */
- {
- case 'N': /* NAK, just stay in this state, */
- if (list > 2)
- printf("\rDbg: NAK for packet %c.", tochar(num));
- num = (--num<0 ? 63:num); /* unless it's NAK for next packet, */
- /* which is just like an ACK for this packet so fall thru to... */
-
- case 'Y': /* ACK */
- if (n != num)
- return(state); /* If wrong ACK, repeat */
- inctry(); /* ++n%64 & ++tries */
- if (len != 0) switch (*recpkt) { /* truncation */
- case 'X': /* single file */
- printmsg("%struncated file",mainhas);
- return('Z');
- case 'Z': /* file group */
- printmsg("%scancelled transfer",mainhas);
- seclose();
- return('B');
- default:
- if (list > 2)
- printf("\rDbg: Bad ACK <%s>",recpkt);
- break;
- }
- if ((size = bufill(packet)) == EOF) /* Get data from file */
- if (errno == 0)
- return('Z'); /* If EOF set state to that */
- else { /* error */
- error(diskfail,errno);
- return('A');
- }
- else
- return('D'); /* Got data, stay in state D */
-
- case 'E': /* Error packet received */
- prerrpkt(recpkt); /* Print it out and */
- seclose();
- return('A'); /* abort */
-
- case FALSE:
- return(state); /* Receive failure, stay in D */
-
- case 'A': /* User abort */
- sendfail();
- return('A');
-
- default: /* Anything else, just "abort" */
- printmsg(badmsg,'Y',type);
- return('A');
- }
- } /* end of sdata() */
-
-
-
- seclose() /* close send-file */
- {
- if (fp != 0) {
- kclose(fp);
- fp = 0;
- filnam = 0;
- }
- return;
- } /* end of seclose() */
-
-
-
- sendfail() /* process user abort */
- {
- abtflag = 0;
- rpack(&len,&num,recpkt); /* ignore next packet */
- error(errmsg); /* then abort */
- seclose();
- return;
- } /* end of sendfail() */
-
-
-
-
- sendsw(ist) /* Send files */
- int ist; /* initial state */
- {
- state = ist;
- n = 0;
- numtry = 0;
- while(TRUE) {
- if (list > 2) {
- outc(CR);
- printf("Dbg: sendsw() state: %c, ",state);
- }
- errdisp(); /* update error display */
- switch(state) {
- case 'S':
- txtout(dots);
- state = sinit();
- break; /* Send-Init */
- case 'F': state = sfile();
- break; /* Send file-init */
- case 'D': state = sdata();
- break; /* Send-Data */
- case 'Z': state = seof();
- break; /* Send-End-of-File */
- case 'B': state = sbreak();
- break; /* Send-Break */
- case 'C':
- seclose();
- return (TRUE); /* Complete */
- case 'A': /* "Abort" */
- default: /* Unknown, fail */
- seclose();
- return (FALSE);
- } }
- } /* end sendsw() */
-
-
-
-
- char seof() /* Send End-Of-File. */
- {
- if (numtry++ > MAXTRY) return('A'); /* If too many tries, "abort" */
-
- spack('Z',n,0,0); /* Send a 'Z' packet */
- if (fp != 0)
- printmsg("** File %s sent OK. ",filnam);
- seclose(); /* close file */
- switch(rpack(&len,&num,recpkt)) {
-
- case 'N': /* NAK, just stay in this state, */
- num = (--num<0 ? 63:num); /* unless it's NAK for next packet, */
-
- case 'Y': /* ACK */
- if (n != num) return(state); /* If wrong ACK, hold out */
- inctry(); /* ++n%64 & ++tries */
- fp = NULL; /* Set flag indicating no file open */
- if (gnxtfl() == FALSE) /* No more files go? */
- return('B'); /* if not, break, EOT, all done */
- return('F'); /* More files, switch state to F */
-
- case 'E': /* Error packet received */
- prerrpkt(recpkt); /* Print it out and */
- return('A'); /* abort */
-
- case FALSE:
- return(state); /* Receive failure, stay in Z */
-
- case 'A': /* User abort */
- sendfail();
- return('A');
-
- default: /* Anything else, just "abort" */
- printmsg(badmsg,'Y',type);
- return('A');
- }
- } /* End of seof() */
-
-
-
-
- char sfile() /* Send File Header. */
- {
- char wk[14], *newfilnam, /* Pointer to file name to send */
- c, *cp; /* char, pointer */
-
- if (numtry++ > MAXTRY) {
- txtout(unable);
- return('A');
- }
- if ( (fp == NULL) && ( (fp = kropen(filnam)) == NULL) ) {
- /* trouble opening file */
- if (filecount != 0) { /* if more to go */
- printf(cannot,filnam);
- gnxtfl();
- numtry = 0; /* permit name message */
- return('F'); /* send next one */
- }
- else {
- error(cannot,filnam);
- return('A');
- } }
-
- strcpy(wk, filnam); /* Copy file name */
- newfilnam = &wk;
- if (newfilnam[1] == ':')
- newfilnam += 2; /* strip CP/M disk-letter */
-
- /* Filenames are always u.c. under CP/M */
- len = strlen(newfilnam);
- if (numtry == 1) /* once per file only */
- printf("Sending <%s> as <%s>\r",filnam,newfilnam);
- if (abtflag != 0) {
- sendfail();
- return('A');
- }
- spack('F',n,len,newfilnam); /* Send an F packet */
-
- switch(rpack(&len,&num,recpkt)) {
-
- case 'N': /* NAK, just stay in this state, */
- num = (--num<0 ? 63:num);
- printmsg("Trouble exchanging params");
- /* unless it's NAK for next packet which is just like an ACK for this packet so fall thru to... */
-
- case 'Y': /* ACK */
- if (n != num) return(state); /* If wrong ACK, stay in F state */
- inctry(); /* ++n%64 & ++tries */
- softeof = FALSE;
- if ( (size = bufill(packet)) == EOF ) { /* null file */
- if (errno == 0) {
- printmsg("File empty.");
- return('Z'); /* on to next */
- }
- else { /* error */
- error(diskfail,errno);
- return('A');
- } }
- else
- return('D'); /* Switch state to D */
-
- case 'E': /* Error packet received */
- prerrpkt(recpkt); /* Print it out and */
- seclose();
- return('A'); /* abort */
-
- case FALSE:
- if (list != 1)
- txtout(trying);
- return(state); /* Receive failure, stay in F state */
-
- case 'A': /* User abort */
- sendfail();
- return('A');
-
- default: /* Anything else, just "abort" */
- printmsg(badmsg,'Y',type);
- return('A');
- }
- } /* end of sfile() */
-
-
-
-
- char sinit() /* Send Initiate */
- /* send this host's parameters and get other side's back.*/
- {
- if (numtry++ > MAXTRY) { /* If too many tries, give up */
- txtout(unable);
- return('A');
- }
- len = spar(packet); /* Fill up init info packet */
- flushinput(); /* Flush pending input */
- spack('S',n,len,packet); /* Send an S packet */
- if (abtflag != 0) {
- sendfail();
- return('A');
- }
- switch(rpack(&len,&num,recpkt)) /* What was the reply? */
- {
-
- case 'Y': /* ACK */
- if (n != num) /* If wrong ACK, stay in S state */
- return(state); /* and try again */
- rpar(recpkt,len); /* Get other side's init info */
- compmode(); /* tell user */
- if (eol == 0) eol = '\n'; /* Check and set defaults */
- if (quote == 0) quote = '#';
- inctry(); /* ++n%64 & ++tries */
- return('F'); /* OK, switch state to F */
-
- case 'I': /* Info-exchange */
- rpar(recpkt,len);
- len = spar(packet);
- compmode();
- spack('Y',n,len,packet);
- rpack(&len,&num,recpkt); /* ignore response */
- return('S');
-
- case 'R': /* Get-packet */
- txtout("R-packet from remote Kermit ");
- rpar(recpkt,len);
- return(state); /* causes retransmission of 'S' */
-
- case 'E': /* Error packet received */
- prerrpkt(recpkt); /* Print it out and */
- return('A'); /* abort */
-
- case FALSE: /* Receive failure */
- if (list != 1)
- txtout(trying);
- case 'N': /* NAK, try it again */
- return(state);
-
- case 'A': /* User abort */
- sendfail();
- return('A');
-
- default: /* Anything else, just "abort" */
- printmsg(badmsg,'Y',type);
- return('A');
- }
- } /* end of sinit() */
-
-
-
- /********************* END of KSEND.C ****************************/
-
-